import base64
import hmac
import random
import time
import urllib.parse as urlParse
from hashlib import sha256

from commonTool.logs.logs_wrapper import LogUtil
from manager import api
from manager.tool import ApiTool

logs = LogUtil()
"""
*******************************************************************************
                签名工具类
*******************************************************************************
"""

apiTool = ApiTool.ApiTool()


class HamcSha256Base64(object):
    # 是否为 dev 加密签名
    is_device = False

    def __init__(self, **kwargs):
        self.kwargs = kwargs

    @logs
    def get_signature(self):
        kwargs = self.kwargs
        paramList = sorted(kwargs.items(), key=lambda x: x[0])
        signStr = ''
        if paramList:
            for i in paramList:
                key = str(i[0])
                value = i[1]
                if value is None or value == '' or len(value) == 0:
                    continue
                # 判断是否替换特殊符号
                value = self.__replace_request_char(str(value))
                signStr = signStr + key + "=" + value + "&"
        else:
            signStr = '&'
        timestamp = str(round(time.time() * 1000))
        randomNumber = str(random.randint(10000000000, 100000000000))
        api.headers['X-Ca-Timestamp'] = timestamp
        api.headers['X-Ca-RandomNumber'] = randomNumber
        signStr = signStr + randomNumber + "&" + timestamp

        signStr = signStr.encode('utf-8')
        secret = self.__is_dev_sign(api.secret).encode('utf-8')

        signature = base64.b64encode(hmac.new(secret, signStr, digestmod=sha256).digest())
        signature = str(signature, 'utf-8')
        api.headers['X-Ca-Signature'] = signature

        print('加密字符串 --> ', signStr)
        logs.info(f'加密字符串 --> {signStr}')
        print('请求头 --> ', api.headers)
        logs.info(f'请求头 --> {api.headers}')

    # 特殊字符替换
    @staticmethod
    @logs
    def __replace_request_char(val):
        is_replace = True
        try:
            is_replace = 'json' not in api.headers['Content-Type']
        except KeyError:
            logs.error('head Content-Type 找不到')

        if is_replace:
            # print('非 json 格式入参 ，特殊字符替换')
            if '！' in val or '￥' in val or '#' in val or '%' in val:
                val = urlParse.quote(val, 'utf-8')
                val = val.replace('%25', '%')
            return val.replace(' ', urlParse.quote(' ', 'utf-8'))
        return val

    # dev 签名替换
    @staticmethod
    @logs
    def __is_dev_sign(val):
        sign_way = {True: 'device', False: 'app'}[HamcSha256Base64.is_device], api.headers['X-Ca-Secversion']
        logs.info(f'\r\n签名方式 --> {sign_way}')
        if HamcSha256Base64.is_device:
            HamcSha256Base64.is_device = False
            api.headers['X-Ca-Key'] = apiTool.buildEnvironmentVariable().get('sn')
            return apiTool.buildEnvironmentVariable().get('deviceSecret')
        return val
